home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Ebooks / Thinking in C++ V2 / C16 / TStash.h < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-25  |  3.4 KB  |  138 lines

  1. //: C16:TStash.h
  2. // From Thinking in C++, 2nd Edition
  3. // Available at http://www.BruceEckel.com
  4. // (c) Bruce Eckel 1999
  5. // Copyright notice in Copyright.txt
  6. // PSTASH using templates
  7. #ifndef TSTASH_H
  8. #define TSTASH_H
  9. #include "../require.h"
  10. #include <cstdlib>
  11.  
  12. // More convenient than nesting in TStash:
  13. enum Owns { no = 0, yes = 1, Default };
  14. // Declaration required:
  15. template<class Type, int sz> class TStashIter;
  16.  
  17. template<class Type, int chunksize = 20>
  18. class TStash {
  19.   int quantity;
  20.   int next;
  21.   Owns _owns; // Flag
  22.   void inflate(int increase = chunksize);
  23. protected:
  24.   Type** storage;
  25. public:
  26.   TStash(Owns owns = yes);
  27.   ~TStash();
  28.   Owns owns() const { return _owns; }
  29.   void owns(Owns newOwns) { _owns = newOwns; }
  30.   int add(Type* element);
  31.   int remove(int index, Owns d = Default);
  32.   Type* operator[](int index);
  33.   int count() const { return next; }
  34.   friend class TStashIter<Type, chunksize>;
  35. };
  36.  
  37. template<class Type, int sz = 20>
  38. class TStashIter {
  39.   TStash<Type, sz>& ts;
  40.   int index;
  41. public:
  42.   TStashIter(TStash<Type, sz>& TS)
  43.     : ts(TS), index(0) {}
  44.   TStashIter(const TStashIter& rv)
  45.     : ts(rv.ts), index(rv.index) {}
  46.   // Jump interator forward or backward:
  47.   void forward(int amount) {
  48.     index += amount;
  49.     if(index >= ts.next) index = ts.next -1;
  50.   }
  51.   void backward(int amount) {
  52.     index -= amount;
  53.     if(index < 0) index = 0;
  54.   }
  55.   // Return value of ++ and -- to be
  56.   // used inside conditionals:
  57.   int operator++() {
  58.     if(++index >= ts.next) return 0;
  59.     return 1;
  60.   }
  61.   int operator++(int) { return operator++(); }
  62.   int operator--() {
  63.     if(--index < 0) return 0;
  64.     return 1;
  65.   }
  66.   int operator--(int) { return operator--(); }
  67.   operator int() {
  68.     return index >= 0 && index < ts.next;
  69.   }
  70.   Type* operator->() {
  71.     Type* t = ts.storage[index];
  72.     if(t) return t;
  73.     require(0,"TStashIter::operator->return 0");
  74.     return 0; // To allow inlining
  75.   }
  76.   // Remove the current element:
  77.   int remove(Owns d = Default){
  78.     return ts.remove(index, d);
  79.   }
  80. };
  81.  
  82. template<class Type, int sz>
  83. TStash<Type, sz>::TStash(Owns owns) : _owns(owns) {
  84.   quantity = 0;
  85.   storage = 0;
  86.   next = 0;
  87. }
  88.  
  89. // Destruction of contained objects:
  90. template<class Type, int sz>
  91. TStash<Type, sz>::~TStash() {
  92.   if(!storage) return;
  93.   if(_owns == yes)
  94.     for(int i = 0; i < count(); i++)
  95.       delete storage[i];
  96.   free(storage);
  97. }
  98.  
  99. template<class Type, int sz>
  100. int TStash<Type, sz>::add(Type* element) {
  101.   if(next >= quantity)
  102.     inflate();
  103.   storage[next++] = element;
  104.   return(next - 1); // Index number
  105. }
  106.  
  107. template<class Type, int sz>
  108. int TStash<Type, sz>::remove(int index, Owns d){
  109.   if(index >= next || index < 0)
  110.     return 0;
  111.   switch(d) {
  112.     case Default:
  113.       if(_owns != yes) break;
  114.     case yes:
  115.       delete storage[index];
  116.     case no:
  117.       storage[index] = 0; // Position is empty
  118.   }
  119.   return 1;
  120. }
  121.  
  122. template<class Type, int sz> inline
  123. Type* TStash<Type, sz>::operator[](int index) {
  124.   // Remove check for shipping application:
  125.   require(index >= 0 && index < next);
  126.   return storage[index];
  127. }
  128.  
  129. template<class Type, int sz>
  130. void TStash<Type, sz>::inflate(int increase) {
  131.   void* v =
  132.     realloc(storage, (quantity+increase)*sizeof(Type*));
  133.   require(v != 0);  // Was it successful?
  134.   storage = (Type**)v;
  135.   quantity += increase;
  136. }
  137. #endif // TSTASH_H ///:~
  138.